package fr.utbm.tx52.stamp.ui.activity;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Geocoder;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.SearchView;
import android.widget.Toast;
import fr.utbm.tx52.stamp.R;
import fr.utbm.tx52.stamp.logic.Contact;
import fr.utbm.tx52.stamp.logic.DataManager;
import fr.utbm.tx52.stamp.logic.reception.PullService;
import fr.utbm.tx52.stamp.logic.utils.FileUtil;
import fr.utbm.tx52.stamp.ui.dialog.Mode;
import fr.utbm.tx52.stamp.ui.fragment.AddressBook;
import fr.utbm.tx52.stamp.ui.fragment.Gallery;
import java.util.ArrayList;

/**
 * Main activity launched when application is launched
 *
 * @author GREA Antoine
 * @author TISSERAND Geoffrey
 */
public class Main extends FragmentActivity
{

	/**
	 * Key for picking a contact
	 */
	private static final int PICK_CONTACT = 1989;
	public static final int PICK_MY_CONTACT = 1990;
	public static final int TAKE_PICTURE = 1991;
	public static final int CHOOSE_IN_GALLERY = 1992;
	static final int DIALOG_LEVEL_ID = 0;
	/**
	 * Used to retrieve preferences
	 */
	public static final String PREFERENCE_LEVEL_KEY = "minimalmode";
	public static final String PREFERENCE_ME_KEY = "phonenumber";
	public static Geocoder geocoder;
	public static boolean launched = false;
	private static ArrayList<Fragment> fragments = new ArrayList<Fragment>();
	/**
	 * UIComponent of the main activity
	 */
	private Menu menu;
	private ActionBar actionBar;
	private TabPager tabPager;
	private ViewPager pager;

	/**
	 * Different level for the application LOW = new user MEDIUM = experiences
	 * user
	 */
	public enum Level
	{

		LOW,
		MEDIUM,
		NULL;
	}

	/**
	 * Different info for both Address book and gallery fragment
	 */
	public enum TabFragment
	{

		ADDRESS_BOOK(AddressBook.class, new int[]
	{
		R.id.address_book_add_contact, R.id.address_book_contact_search
	}, R.string.address_book),
		GALLERY(Gallery.class, new int[]
	{
		R.id.gallery_sort_order, R.id.gallery_sort
	}, R.string.inbox);
		private Class<? extends Fragment> class_;
		private int[] ressources;
		private int name;

		public int getName()
		{
			return name;
		}

		public int[] getRessources()
		{
			return ressources;
		}

		public Class<? extends Fragment> getClass_()
		{
			return class_;
		}

		private TabFragment(Class<? extends Fragment> clazz, int[] ressources, int name)
		{
			this.class_ = clazz;
			this.ressources = ressources;
			this.name = name;
		}
	}

	/**
	 * Use to implement the tabs
	 */
	public static class TabListener implements ActionBar.TabListener
	{

		private TabFragment tabFragment;
		private Main main;
		private ViewPager pager;

		public TabListener(TabFragment tabFragment, ViewPager pager, Main main)
		{
			this.tabFragment = tabFragment;
			this.main = main;
			this.pager = pager;
		}

		public void refreshItems()
		{
			main.setItemsVisible(true, tabFragment);
			for (TabFragment other : TabFragment.values())
			{
				if (other != tabFragment)
				{
					main.setItemsVisible(false, other);
				}
			}
		}

		/*
		 * The following are each of the ActionBar.TabListener callbacks
		 */
		public void onTabSelected(Tab tab, android.app.FragmentTransaction ft)
		{
			refreshItems();
			pager.setCurrentItem(tabFragment.ordinal());
		}

		public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft)
		{
		}

		public void onTabReselected(Tab tab, android.app.FragmentTransaction ft)
		{
			// User selected the already selected tab. Usually do nothing.
		}
	}

	public static class TabPager extends FragmentPagerAdapter
	{

		public TabPager(android.support.v4.app.FragmentManager fm)
		{
			super(fm);
		}

		@Override
		public int getCount()
		{
			return Main.fragments.size();
		}

		@Override
		public Fragment getItem(int position)
		{
			return Main.fragments.get(position);
		}
	}

	private void setItemsVisible(boolean state, TabFragment tabFragment)
	{
		if (menu == null)
		{
			return;
		}
		for (int id : tabFragment.ressources)
		{
			MenuItem menuItem = menu.findItem(id);
			menuItem.setVisible(state);
		}
	}

	public void draw()
	{
		SharedPreferences preferences = getPreferences(MODE_PRIVATE);
		Log.i("pref", Level.values()[preferences.getInt(PREFERENCE_LEVEL_KEY, Level.NULL.ordinal())].toString());

		switch (Level.values()[preferences.getInt(PREFERENCE_LEVEL_KEY, Level.NULL.ordinal())])
		{
			case LOW:
				getActionBar().hide();
				final Gallery gallery = new Gallery();
				FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
				fragmentTransaction.add(android.R.id.content, gallery);
				fragmentTransaction.commit();
				break;
			case MEDIUM:
				setContentView(R.layout.main);
				actionBar = getActionBar();
				actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
				actionBar.setDisplayHomeAsUpEnabled(false);
				pager = (ViewPager) findViewById(R.id.pager);
				for (TabFragment tabFragment : TabFragment.values())
				{
					try
					{
						fragments.add(tabFragment.getClass_().newInstance());
					}
					catch (InstantiationException ex)
					{
						Log.e(getClass().getSimpleName(), "", ex);
					}
					catch (IllegalAccessException ex)
					{
						Log.e(getClass().getSimpleName(), "", ex);
					}
					Tab tab = actionBar.newTab().setText(tabFragment.getName()).setTabListener(new TabListener(tabFragment, pager, this));
					actionBar.addTab(tab);
					if (tabFragment == TabFragment.GALLERY)
					{
						tab.select();
					}
				}
				tabPager = new TabPager(getSupportFragmentManager());
				pager.setAdapter(tabPager);
				pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener()
				{

					public void onPageScrolled(int i, float f, int i1)
					{
					}

					public void onPageSelected(int i)
					{
						Log.d("Main", "tab = " + i);
						if (i % fragments.size() == i)
						{
							actionBar.getTabAt(i).select();
						}
					}

					public void onPageScrollStateChanged(int i)
					{
					}
				});

				pager.setCurrentItem(TabFragment.GALLERY.ordinal());

				break;
			default:
				showModeDialog();
				break;
		}

	}

	/**
	 * Called when the activity is first created.
	 */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		//Images.add(new Images("toto", "sample_thumb_0", "", "", ""));
		//Images.add(new Images("toto", "sample_thumb_1", "", "", ""));
		launched = true;

		FileUtil.checkOrCreatePicturesFolder();

		DataManager.fixUserPhoneNumber(this);

		geocoder = new Geocoder(getBaseContext());

		if (PullService.getInstance() == null)
		{
			startService(new Intent(this, PullService.class));
		}

		this.draw();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		this.menu = menu;
		MenuInflater menuInflater = getMenuInflater();
		menuInflater.inflate(R.menu.main, menu);


		MenuItem addContact = menu.findItem(R.id.address_book_add_contact);
		addContact.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener()
		{

			public boolean onMenuItemClick(MenuItem item)
			{
				Intent intentContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
				startActivityForResult(intentContact, PICK_CONTACT);
				return true;
			}
		});

		SearchView search = (SearchView) menu.findItem(R.id.address_book_contact_search).getActionView();
		search.setOnQueryTextListener(new SearchView.OnQueryTextListener()
		{

			public boolean onQueryTextSubmit(String query)
			{
				return false;
			}

			public boolean onQueryTextChange(String newText)
			{
				AddressBook.get(Main.this).getAdapter().setFilter(newText);
				return true;
			}
		});

		search.setOnCloseListener(new SearchView.OnCloseListener()
		{

			public boolean onClose()
			{
				AddressBook.get(Main.this).getAdapter().setFilter("");
				return false;
			}
		});

		setItemsVisible(false, TabFragment.ADDRESS_BOOK);
		setItemsVisible(true, TabFragment.GALLERY);
		
		menu.findItem(R.id.preferences).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener(){

			public boolean onMenuItemClick(MenuItem item)
			{
	    		Intent myIntent = new Intent(getApplicationContext(), Preferences.class);
	            startActivityForResult(myIntent, 0);
				return true;
			}
		});

		// Calling super after populating the menu is necessary here to ensure
		// that the
		// action bar helpers have a chance to handle this event.
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	/**
	 * When we got a result
	 */
	public void onActivityResult(int requestCode, int resultCode, Intent intent)
	{
		if (resultCode == RESULT_CANCELED)
		{
			Toast.makeText(this, "Annulé", Toast.LENGTH_SHORT).show();
			return;
		}

		SharedPreferences preferences = getPreferences(MODE_PRIVATE);
		switch (requestCode)
		{
			case PICK_CONTACT:
				fr.utbm.tx52.stamp.logic.Contact newContact = fr.utbm.tx52.stamp.logic.Contact.getContactFromUri(this, intent.getData());
				if (newContact == null)
				{
					return;
				}
				DataManager.addAssociatedContacts(this, newContact);
				AddressBook.get(this).getAdapter().addContact(newContact);
				break;
			case PICK_MY_CONTACT:
				Contact me = Contact.getContactFromUri(this, intent.getData());
				preferences.edit().putString(Main.PREFERENCE_ME_KEY, me.getPhoneNumber()).apply();
				AddressBook.get(this).getAdapter().setMe(me);
				break;
			case TAKE_PICTURE:
			case CHOOSE_IN_GALLERY:
				final Intent share = new Intent(this, Share.class);
				share.setData(intent.getData());
				share.putExtras(intent);
				startActivity(share);
				break;
		}
	}

	@Override
	public void onDestroy()
	{
		super.onDestroy();
		launched = false;
	}

	void showModeDialog()
	{
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Mode newFragment = Mode.newInstance(this);
		newFragment.show(ft, "dialog");
	}
}
